package org.fhnw.aigs.server.gui; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; /*------------------------------------------------------------------------------ * IMPORTANT NOTE!!! * ################# * I assume that this class was written by Rob Camick. It was found at: * https://tips4java.wordpress.com/2008/10/15/limit-lines-in-document/ * Unfortunately, no author nor license information was added to this class * nor mentioned on the above stated website. * The class "LimitLinesDocumentListener"(.java) is used in many projects * according the results of the web search engine of your choice. * The class has most times the license GPLv2/3. * I ASSUME GULLIBLE THAT THIS CLASS CAN BE USED UNDER A GPL-COMPATIBLE LICENSE * LIKE GPLV3, WHICH IS USED BY AIGS. PLEASE CONTACT A MAINTAINER OF AGIS IF * THIS ASSUMPTION IS A FALLACY. * ----------------------------------------------------------------------------- */ /** * A class to control the maximum number of lines to be stored in a Document<br> * Excess lines can be removed from the start or end of the Document * depending on your requirement.<br><br> * a) if you append text to the Document, then you would want to remove lines from the start.<br> * b) if you insert text at the beginning of the Document, then you would want to remove lines from the end.<br> * @author Rob Camick (Adapted by Raphael Stoeckli) * @version 1.0 */ public class LimitLinesDocumentListener implements DocumentListener { private int maximumLines; private boolean isRemoveFromStart; /** * Specify the number of lines to be stored in the Document. * Extra lines will be removed from the start of the Document. * @param maximumLines Number of displayed lines */ public LimitLinesDocumentListener(int maximumLines) { this(maximumLines, true); } /** * Specify the number of lines to be stored in the Document. * Extra lines will be removed from the start or end of the Document, * depending on the boolean value specified. * @param maximumLines Number of displayed lines * @param isRemoveFromStart If true, the lines will be removed at the top of the document, otherwise at the bottom */ public LimitLinesDocumentListener(int maximumLines, boolean isRemoveFromStart) { setLimitLines(maximumLines); this.isRemoveFromStart = isRemoveFromStart; } /** * Return the maximum number of lines to be stored in the Document * @return Maximum number of lines */ public int getLimitLines() { return maximumLines; } /** * Set the maximum number of lines to be stored in the Document * @param maximumLines Maximum number of lines */ public void setLimitLines(int maximumLines) { if (maximumLines < 1) { String message = "Maximum lines must be greater than 0"; throw new IllegalArgumentException(message); } this.maximumLines = maximumLines; } // Handle insertion of new text into the Document /** * Method to handle the insertation of new text into the document * @param e DocumentEvent to monitor */ @Override public void insertUpdate(final DocumentEvent e) { // Changes to the Document can not be done within the listener // so we need to add the processing to the end of the EDT SwingUtilities.invokeLater( new Runnable() { @Override public void run() { removeLines(e); } }); } /** * Dummy: Implemented method. Must not be specified in this case * @param e DocumentEvent to monitor */ @Override public void removeUpdate(DocumentEvent e) {} /** * Dummy: Implemented method. Must not be specified in this case * @param e DocumentEvent to monitor */ @Override public void changedUpdate(DocumentEvent e) {} /** * Method to remove lines from the Document when necessary * @param e DocumentEvent to monitor */ private void removeLines(DocumentEvent e) { // The root Element of the Document will tell us the total number // of line in the Document. Document document = e.getDocument(); Element root = document.getDefaultRootElement(); while (root.getElementCount() > maximumLines) { if (isRemoveFromStart) { removeFromStart(document, root); } else { removeFromEnd(document, root); } } } /** * Method to remove lines from the start of the Document * @param document Document to handle * @param root Root element of the document */ private void removeFromStart(Document document, Element root) { Element line = root.getElement(0); int end = line.getEndOffset(); try { document.remove(0, end); } catch(BadLocationException ble) { System.out.println(ble); } } /** * Method to remove lines from the end of the Document * @param document Document to handle * @param root Root element of the document */ private void removeFromEnd(Document document, Element root) { // We use start minus 1 to make sure we remove the newline // character of the previous line Element line = root.getElement(root.getElementCount() - 1); int start = line.getStartOffset(); int end = line.getEndOffset(); try { document.remove(start - 1, end - start); } catch(BadLocationException ble) { System.out.println(ble); } } }